package com.gf.common.util;

import java.util.Date;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.gf.common.bean.Queue;

/**
 * 邮件列队发送系统<br>
 * singlton
 * @author zhuguifeng guifeng.net@gmail.com
 * @version 创建时间：2012-10-4 下午9:35:44
 */
@Component("mailQueueHelper")
public class MailQueueHelper {

	private static Log logger = LogFactory.getLog(MailHelper.class);
	private static final JavaMailSender MAILSENDER = SpringUtils
			.getBean("mailSender");
	private static Queue queue = null;
	private static Object mutex = null;
	// 该服务是否关闭
	private boolean isClose;
	private Thread sendThread;

	private static MailQueueHelper helper = new MailQueueHelper();

	/**
	 * 构造函数为private
	 */
	private MailQueueHelper() {
		logger.info("初始化邮件队列发送系统");
		isClose = false;

		queue = new Queue();
		mutex = new Object();
		sendThread = new Thread(sendRun);
		sendThread.start();
	}

	public static MailQueueHelper getHelper() {
		return helper;
	}

	/**
	 * run
	 */
	private Runnable sendRun = new Runnable() {
		@Override
		public void run() {
			while (!isClose) {
				// 持续发送
				while (!isEmpty()) {
					doSend(queue.poll());
				}
				// 无消息 则等待消息
				synchronized (mutex) {
					try {
						mutex.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	};

	/**
	 * 发送普通邮件
	 * 
	 * @param smm
	 */
	public void sendSMM(SimpleMailMessage smm) {
		queue.add(smm);
		// 不能同时唤醒 唤醒执行队列
		synchronized (mutex) {
			mutex.notify();
		}
	}

	/**
	 * 邮件发送:单纯文本
	 * 
	 * @param toAddress
	 * @param title
	 * @param content
	 */
	public void sendSMM(String FROM_ADDRESS, String toAddress, String title,
			String content) {
		SimpleMailMessage message = new SimpleMailMessage();
		message.setFrom(FROM_ADDRESS);
		message.setTo(toAddress);
		if (!StringUtils.hasLength(title)) {
			title = "无主题";
		}
		message.setSubject(title);
		message.setText(content);
		message.setSentDate(new Date());

		sendSMM(message);
	}

	/**
	 * 发送HTML类型的邮件
	 * 
	 * @param mmm
	 */
	public void sendMMM(MimeMessage mmm) {
		queue.add(mmm);

		synchronized (mutex) {
			mutex.notify();
		}
	}

	/**
	 * 邮件发送:html格式的文本
	 * 
	 * @param toAddress
	 * @param title
	 * @param content
	 * @throws MessagingException
	 */
	public void sendHtmlMail(String FROM_ADDRESS, String toAddress,
			String title, String content) throws MessagingException {
		MimeMessage mimeMessage = MAILSENDER.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
		helper.setFrom(FROM_ADDRESS);
		helper.setTo(toAddress);
		if (!StringUtils.hasLength(title)) {
			title = "无主题";
		}
		helper.setSubject(title);
		helper.setText(content, true);
		helper.setSentDate(new Date());

		sendMMM(mimeMessage);
	}

	/**
	 * 根据列队里取出的邮件类型进行发送
	 */
	private void doSend(Object obj) {
		logger.info("发送邮件:" + obj);

		if (obj instanceof SimpleMailMessage) {
			MAILSENDER.send((SimpleMailMessage) obj);
		} else if (obj instanceof MimeMessage) {
			MAILSENDER.send((MimeMessage) obj);
		}
	}

	/**
	 * 注意queue!=null
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		return queue != null && queue.isEmpty();
	}

	/**
	 * 强行关闭
	 */
	@SuppressWarnings("deprecation")
	public void close() {
		logger.info("关闭邮件队列发送系统");
		isClose = true;
		queue.clear();
		if (queue.isEmpty()) {
			queue = null;
		}
		sendThread.stop();
		sendThread = null;
	}

}
